#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <cassert>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <unistd.h>

/* Note: this program is totally wrong */

using namespace std; 

#define INF 1E100
#define N 	16

struct node_t {
	int 	used; 	// if the place we have been there, then its corresponding bit is set
	double 	dist; 	// distance from start point to here
}; 


double 	a[N][2]; 
int 	n; 

node_t node[N][N]; 


int main()
{
	int i, j, k, last_used;
	double d, md; 
	node_t *p; 
	double x0, y0; 
	double x1, y1; 
	double x, y; 
	
	freopen("p1433_1.in", "r", stdin); 
	cin>>n; 
	for (i=0; i<n; i++) {
		cin>>a[i][0]>>a[i][1]; 
	} 

	for (j=0; j<n; j++) {
		node[0][j].used = (1<<j); 
		x = a[j][0]; 
		y = a[j][1]; 
		d = sqrt(x*x + y*y); 
		node[0][j].dist = d; 
		printf("node[0][%d]:  x=%6.2lf y=%6.2lf d=%.2lf used=%04x\n", j, x, y, d, node[0][j].used); 
	}
	
	for (i=1; i<n; i++) {
		for (j=0; j<n; j++) {
			int q=-1; 
			md = INF; 
			last_used = 0xffffff; 
			for (k=0; k<n; k++) {
				p = &node[i-1][k]; 
				if (p->used & (1<<j))
					continue; 
				x0 = a[k][0]; 
				y0 = a[k][1]; 
				x1 = a[j][0]; 
				y1 = a[j][1]; 
				x = x1 - x0; 
				y = y1 - y0; 
				d = p->dist + sqrt(x*x + y*y); 
				if (d<md) {
					md = d; 
					last_used = p->used; 
					q = k; 
				}
			}
			p = &node[i][j]; 
			p->used = last_used | (1<<j); 
			p->dist = md; 
			printf("node[%d][%d]:  last_used=%04x used=%04x q=%d d=%.2lf \n", i, j, last_used, p->used, q, md==INF?-1:md); 
		}
	}
	d = INF; 
	for (i=0; i<n; i++) {
		p = &node[n-1][i]; 
		d = min(d, p->dist); 
	}
	printf("%.2lf\n", d); 
	return 0; 	
}



